package com.dj.dormitory.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dj.dormitory.commonutils.BCPEUtils;
import com.dj.dormitory.commonutils.JWTUtil;
import com.dj.dormitory.commonutils.Result;

import com.dj.dormitory.entity.User;
import com.dj.dormitory.entity.excel.UserDataExcel;
import com.dj.dormitory.entity.vo.SignVo;
import com.dj.dormitory.service.StudentService;
import com.dj.dormitory.service.UserService;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author DJ同学
 * @since 2021-01-24
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private StudentService studentService;

    @RequestMapping("/list")
    public Result  getAll(){
        return Result.ok().data("data",userService.list());
    }
    //用户登录
    @PostMapping("/login")
    public Result login(@RequestBody User input_user){
        User user = userService.login(input_user);
        if(user!=null){
            boolean isRightPassword = BCPEUtils.matches(input_user.getPassword(),
                    user.getPassword());
            if(isRightPassword){
                //登录成功
                Integer studentId = -1;
                if(user.getType()==2){
                    //获得studentId
                    studentId = studentService.getSIdByUserId(user.getId());
                }
                String jwtToken = JWTUtil.getJwtToken(new SignVo(user.getId(),user.getUserName(),user.getType(),studentId));
                Map<String,Object> map = new HashMap<>();
                map.put("token",jwtToken);
                map.put("studentId",studentId);
                map.put("name",user.getName());//用户姓名
                map.put("type",user.getType());//用户类型
                return Result.ok().data("data",map).message("登录成功");
            }else{
                return Result.error().message("用户名或密码错误");
            }
        }else{
            return Result.error().message("用户名或密码错误");
        }
    }
    //修改密码
    @PostMapping("editPassword")
    public Result editPassword(@RequestBody Map map,HttpServletRequest request){
          String old_password = (String)map.get("old_password");
          String new_password = (String)map.get("new_password");
          String again_password = (String)map.get("again_password");
          if(new_password.equals(again_password)){
              Integer userId = (Integer) request.getAttribute("userId");
              Integer type = (Integer) request.getAttribute("type");
              //数据库中获得密码
              QueryWrapper<User> wrapper  =  new QueryWrapper<>();
              wrapper.eq("id",userId);
              wrapper.eq("type",type);
              User user = userService.getOne(wrapper);
              //判断密码是否正确
              if(BCPEUtils.matches(old_password,user.getPassword())){
                  //更新密码
                  user.setPassword(BCPEUtils.encode(new_password));
                  boolean b = userService.updateById(user);
                  return b?Result.ok().message("更新密码正确"):Result.ok().message("更新密码错误");
              }else{
                  return Result.error().message("旧密码输入错误");
              }
          }else{

              return Result.error().message("前后两次密码输入不一致");
          }
    }
    //条件查询
    @PostMapping("/partList")
    public Result getPartList(@RequestBody Map input_data){
        //传入 用户名 和 类型（0 1 2）
        Page<User> page = userService.getPartList(input_data);
        return Result.ok().data("users",page);
    }
    //新增用户
    @PostMapping("/add")
    public Result addUser(@RequestBody User input_user){
        input_user.setPassword(BCPEUtils.encode(input_user.getPassword()));
        System.out.println(input_user.getPassword());
        try{//用户名没有唯一性的时候，抛出异常
            userService.save(input_user);
            return Result.ok().message("新增用户成功");
        }catch (Exception e){
            e.printStackTrace();
            return Result.error().message("新增用户失败");
        }
    }
    //根据id获得用户
    @GetMapping("/getOne")
    public Result getOne(HttpServletRequest request){
        Integer id = (Integer) request.getAttribute("userId");
        User user = userService.getById(id);
        return Result.ok().data("user",user);
    }
    //编辑用户
    @PostMapping("/edit")
    public Result editUser(@RequestBody User input_user){
        System.out.println("edit");
        System.out.println(input_user);
        try {
            boolean edit = userService.updateById(input_user);
            return  edit ? Result.ok().message("修改用户信息成功"):Result.error().message("修改用户信息失败");
        }catch (Exception e){
            e.printStackTrace();
            return Result.error().message("修改用户信息失败");
        }
    }
    //删除用户
    @PostMapping("/deleteOne/{id}")
    public Result deleteOne(@PathVariable(value="id") Integer delete_id){
        System.out.println(delete_id);
        boolean delete = userService.removeById(delete_id);
        return  delete ? Result.ok().message("删除用户成功"):Result.error().message("删除用户失败");
    }
    // 批量删除用户 涉及到删除学生问题（未启用）
    @PostMapping("/deletePart/{userIdsStr}")
    public Result deletePart(@PathVariable("userIdsStr")List<String> ids){
        boolean delete = userService.removeByIds(ids);
        return  delete ? Result.ok().message("删除用户成功"):Result.error().message("删除用户失败");
    }

    @PostMapping("/addUsers")
    public Result addUsers(@RequestParam("uploadFile") MultipartFile file) throws IOException {
        boolean save = userService.addUsers(file);
        return  save ? Result.ok().message("Excel导入用户成功"):Result.error().message("Excel导入用户失败");
    }
    @GetMapping("/exportAll")
    public Result exportAll(HttpServletResponse response) throws IOException {

        List<UserDataExcel> listExcel = new ArrayList<>();
        List<User> list = userService.list();
        for(int i = 0;i<list.size();i++){
            UserDataExcel dataExcel = new UserDataExcel();
            BeanUtils.copyProperties(list.get(i),dataExcel);
            if(list.get(i).getType()!=null){
                switch (list.get(i).getType()){
                    case 0:
                        dataExcel.setTypeStr("管理员");
                        break;
                    case 1:
                        dataExcel.setTypeStr("宿管员");
                        break;
                }
            }
            dataExcel.setPassword("***");
            listExcel.add(dataExcel);
        }
        //文件名需要这样写，不能在setHeader直接写中文名，否则下载的文件名字为空，只有后缀
        String fileName = new String("用户信息.xlsx".getBytes(), StandardCharsets.ISO_8859_1);
        response.setContentType("application/msexcel");
        response.setCharacterEncoding("utf8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName );
        EasyExcel.write(response.getOutputStream(), UserDataExcel.class)
                .sheet("sheet")
                .doWrite(listExcel);
        return Result.ok().message("下载成功");
    }

    //根据type获得信息
    @PostMapping("/getUserByType/{type}")
    public Result getUserByType(@PathVariable String type){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("type",type);
        List<User> list = userService.list(wrapper);
        return Result.ok().data("users",list);
    }

}

